package yxy.banana.socket;

public class NetworkElement {
	private static final String StringFormat = "NE.%d.%d.%d";

	public static enum Field {
		System, Cluster, Channel
	}

	private int system = 0;// 1字节
	private int cluster = 0;// 1字节
	private int channel = 0;// 2字节
	private long value = 0;

	public static NetworkElement assemble(long value) {
		NetworkElement instance = new NetworkElement();
		instance.update(value);
		return instance;
	}

	public static NetworkElement assemble(int system, int cluster, int channel) {
		NetworkElement instance = new NetworkElement();
		instance.update(system, cluster, channel);
		return instance;
	}

	public static long value(int system, int cluster, int channel) {
		long a = ((system & 0x00000000000000FFL) << 24);
		long b = ((cluster & 0x00000000000000FFL) << 16);
		long c = ((channel & 0x000000000000FFFFL) << 0);
		return a | b | c;
	}

	public static int field(long value, Field field) {
		long result = 0;
		switch (field) {
		case System:
			result = ((value >> 24) & 0x00000000000000FFL);
			break;
		case Cluster:
			result = ((value >> 16) & 0x00000000000000FFL);
			break;
		case Channel:
			result = ((value >> 0) & 0x000000000000FFFFL);
			break;
		}
		return (int) result;
	}

	public void setSystem(int cluster) {
		this.system = cluster;
		this.update();
	}

	public void setCluster(int bundle) {
		this.cluster = bundle;
		this.update();
	}

	public void setChannel(int channel) {
		this.channel = channel;
		this.update();
	}

	public void update(int system, int cluster, int channel) {
		this.system = system;
		this.cluster = cluster;
		this.channel = channel;
		this.update();
	}

	public void update(long value) {
		this.system = (int) ((value >> 24) & 0x00000000000000FFL);
		this.cluster = (int) ((value >> 16) & 0x00000000000000FFL);
		this.channel = (int) ((value >> 0) & 0x000000000000FFFFL);
		this.update();
	}

	private void update() {
		long a = ((this.system & 0x00000000000000FFL) << 24);
		long b = ((this.cluster & 0x00000000000000FFL) << 16);
		long c = ((this.channel & 0x000000000000FFFFL) << 0);
		this.value = a | b | c;
	}

	public int system() {
		return system;
	}

	public int cluster() {
		return cluster;
	}

	public int channel() {
		return channel;
	}

	public long value() {
		return value;
	}

	public boolean match(NetworkElement another, long mask) {
		long one = this.value & mask;
		long two = another.value & mask;
		return one == two;
	}

	@Override
	public String toString() {
		return String.format(StringFormat, this.system, this.cluster, this.channel);
	}

	public static void main(String[] args) {
		System.err.println(NetworkElement.assemble(1, 123, 2).value);
	}
}
